﻿#pragma once

#include "ISistema.h"
#include "Prueba.h"

class CasoDePrueba : public Prueba
{
public:
	CasoDePrueba(Puntero<ISistema> (*inicializar)(nat VELOCIDAD_OMNIBUS, nat VELOCIDAD_AVION, nat COSTO_OMNIBUS, nat COSTO_AVION, nat CAPACIDAD_OMNIBUS, nat CAPACIDAD_AVION, nat MAX_CIUDADES, nat MAX_EXCURSIONES));
protected:
	void CorrerPruebaConcreta();
	Cadena GetNombre() const;

private:
	Puntero<ISistema> (*inicializar)(nat VELOCIDAD_OMNIBUS, nat VELOCIDAD_AVION, nat COSTO_OMNIBUS, nat COSTO_AVION, nat CAPACIDAD_OMNIBUS, nat CAPACIDAD_AVION, nat MAX_CIUDADES, nat MAX_EXCURSIONES);
	Puntero<ISistema> InicializarSistema(nat VELOCIDAD_OMNIBUS = 50, nat VELOCIDAD_AVION = 100, nat COSTO_OMNIBUS = 10, nat COSTO_AVION = 100, nat CAPACIDAD_OMNIBUS = 40, nat CAPACIDAD_AVION = 200, nat MAX_CIUDADES = 30, nat MAX_EXCURSIONES = 30);
	void InicializarCiudad(Puntero<ISistema> interfaz);
	void InicializarAtraccion(Puntero<ISistema> interfaz);
	void InicializarExcursion(Puntero<ISistema> interfaz);
	void InicializarConexion(Puntero<ISistema> interfaz);
	void InicializarAtraccionesAVisitar(Puntero<ISistema> interfaz);

	bool ignorarOK;
	void Verificar(TipoRetorno obtenido, TipoRetorno esperado, Cadena comentario);
	template <class T>
	void Verificar(const T& obtenido, const T& esperado, Cadena comentario);
	template <class T>
	void VerificarConjuntos(Iterador<T> obtenidos, Iterador<T> esperados, Cadena comentarioEncontrado, Cadena comentarioFalta, Cadena comentarioSobra);
	template <class T>
	void VerificarSecuencias(Iterador<T> obtenidos, Iterador<T> esperados, Cadena comentarioEncontrado, Cadena comentarioFalta, Cadena comentarioSobra);
	template <class T>
	bool SonIguales(Iterador<T> obtenidos, Iterador<T> esperados) const;
	template <class T>
	bool Pertenece(const T& obtenido, Iterador<T> esperados) const;
	void VerificarConsultaAtraccion(Tupla<TipoRetorno, pAtraccion> obtenido, Tupla<TipoRetorno, pAtraccion> esperado, Cadena comentario);
	void VerificarTransportes(Tupla<TipoRetorno, Iterador<Tupla<Cadena, Cadena, TipoTransporte, nat>>> obtenido, Tupla<TipoRetorno, Iterador<Tupla<Cadena, Cadena, TipoTransporte, nat>>> esperado, Cadena comentario);
	void VerificarCiudadMejoresAtracciones(Tupla<TipoRetorno, pCiudad> obtenido, Tupla<TipoRetorno, pCiudad> esperado, Cadena comentario);
	void VerificarConsultaExcursion(Tupla<TipoRetorno, pExcursion> obtenido, Tupla<TipoRetorno, pExcursion> esperado, Cadena comentario);
	void VerificarListadoCiudades(Tupla<TipoRetorno, Iterador<pCiudad>> obtenido, Tupla<TipoRetorno, Iterador<pCiudad>> esperado, Cadena comentario);
	void VerificarHayCamino(Tupla<TipoRetorno, bool> obtenido, Tupla<TipoRetorno, bool> esperado, Cadena comentario);
	void VerificarAtraccionesAVisitarA(Tupla<TipoRetorno, Iterador<pAtraccion>> obtenido, Tupla<TipoRetorno, Iterador<pAtraccion>> esperado, Cadena comentario);
	void VerificarAtraccionesAVisitarB(Tupla<TipoRetorno, Iterador<pAtraccion>> obtenido, Tupla<TipoRetorno, Iterador<pAtraccion>> esperado, Cadena comentario);
	void VerificarMaximosViajantes(Tupla<TipoRetorno, nat> obtenido, Tupla<TipoRetorno, nat> esperado, Cadena comentario);
	void VerificarCiudadesEsenciales(Tupla<TipoRetorno, Iterador<pCiudad>> obtenido, Tupla<TipoRetorno, Iterador<pCiudad>> esperado, Cadena comentario);
	void VerificarExcursiones(Tupla<TipoRetorno, pExcursion> obtenido, Tupla<TipoRetorno, pExcursion> esperado, Cadena comentario);
	bool SonIguales(const pCiudad& obtenido, const pCiudad& esperado) const;
	Cadena ObtenerTexto(const pCiudad& c) const;
	bool SonIguales(const pAtraccion& obtenido, const pAtraccion& esperado) const;
	Cadena ObtenerTexto(const pAtraccion& a) const;
	bool SonIguales(const pExcursion& obtenido, const pExcursion& esperado) const;
	Cadena ObtenerTexto(const pExcursion& e) const;
	bool SonIguales(const Tupla<nat, int, Cadena>& obtenido, const Tupla<nat, int, Cadena>& esperado) const;
	Cadena ObtenerTexto(const Tupla<nat, int, Cadena>& t) const;
	bool SonIguales(const Tupla<pCiudad, TipoTransporte, nat, nat>& obtenido, const Tupla<pCiudad, TipoTransporte, nat, nat>& esperado) const;
	Cadena ObtenerTexto(const Tupla<pCiudad, TipoTransporte, nat, nat>& t) const;
	bool SonIguales(const Tupla<Cadena, Cadena, TipoTransporte, nat>& obtenido, const Tupla<Cadena, Cadena, TipoTransporte, nat>& esperado) const;
	Cadena ObtenerTexto(const Tupla<Cadena, Cadena, TipoTransporte, nat>& t) const;
	Cadena ObtenerTexto(const TipoTransporte& t) const;
	Cadena ObtenerTexto(nat n) const;

	void PruebaOKIngresoCiudad();
	void PruebaOKIngresoAtraccion();
	void PruebaOKCalificarAtraccion();
	void PruebaOKAltaConexion();
	void PruebaOKConsultaAtraccion();
	void PruebaOKTransportes();
	void PruebaOKCiudadMejoresAtracciones();
	void PruebaOKIngresoExcursionItinerario();
	void PruebaOKIngresoExcursionDistancia();
	void PruebaOKIngresoExcursionCosto();
	void PruebaOKConsultaExcursion();
	void PruebaOKListadoCiudades();
	void PruebaOKHayCamino();
	void PruebaOKAtraccionesAVisitarA();
	void PruebaOKAtraccionesAVisitarB();
	void PruebaOKMaximosViajantes();
	void PruebaOKCiudadesEsenciales();

	void PruebaERRORIngresoCiudad();
	void PruebaERRORIngresoAtraccion();
	void PruebaERRORCalificarAtraccion();
	void PruebaERRORAltaConexion();
	void PruebaERRORConsultaAtraccion();
	void PruebaERRORTransportes();
	void PruebaERRORCiudadMejoresAtracciones();
	void PruebaERRORIngresoExcursionItinerario();
	void PruebaERRORIngresoExcursionDistancia();
	void PruebaERRORIngresoExcursionCosto();
	void PruebaERRORConsultaExcursion();
	void PruebaERRORListadoCiudades();
	void PruebaERRORHayCamino();
	void PruebaERRORAtraccionesAVisitarA();
	void PruebaERRORAtraccionesAVisitarB();
	void PruebaERRORMaximosViajantes();
	void PruebaERRORCiudadesEsenciales();

	Array<pCiudad> ObtenerCiudadesDelSistema();
	Array<pAtraccion> ObtenerAtraccionesDelSistema();

	Cadena m_PlantillaTransporte;
};